package com.dks.repository.impl.student;

import com.dks.dto.BaseIdRequestDto;
import com.dks.dto.student.UserClassHourPackageBuyDto;
import com.dks.dto.student.UserClassHourPackageGiveDto;
import com.dks.dto.student.UserClassHourPackageTransferDto;
import com.dks.exception.BaseException;
import com.dks.mapper.*;
import com.dks.models.UserCashCoupon;
import com.dks.models.Users;
import com.dks.models.WechatUserInfo;
import com.dks.models.pay.CashCoupon;
import com.dks.models.student.ClassHourPackage;
import com.dks.models.student.UserClassHourPackage;
import com.dks.repository.IUserClassHourPackageRepository;
import com.dks.repository.impl.pay.WXRequest;
import com.dks.result.Result;
import com.dks.result.ResultInfo;
import com.dks.result.ResultModel;
import com.dks.util.PageInfo;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import io.jsonwebtoken.lang.Collections;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户课时包相关
 */
@Repository
public class UserClassHourPackageRepository implements IUserClassHourPackageRepository {

    @Autowired
    private UserClassHourPackageMapper userClassHourPackageMapper;
    @Autowired
    private ClassHourPackageMapper classHourPackageMapper;
    @Autowired
    private UsersMapper usersMapper;
    @Autowired
    private WXRequest wxRequest;
    @Autowired
    private WechatUserInfoMapper wechatUserInfoMapper;
    @Autowired
    private CashCouponMapper cashCouponMapper;
    @Autowired
    private UserCashCouponMapper userCashCouponMapper;

    DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");


    /**
     * 课时包-赠送
     *
     * @author evan
     */
    @Override
    @Transactional
    public ResultModel<Object> give(UserClassHourPackageGiveDto giveDto) throws BaseException, WxPayException {
        LocalDateTime now = LocalDateTime.now();
        //判断用户是否注册
        Users targetUser = usersMapper.getByPhoneNum(giveDto.getTargetUserPhoneNum());
        if (targetUser == null) {
            return Result.makeResult(ResultInfo.ERR_USERS_001);
        }
        WechatUserInfo wechatUserInfo = wechatUserInfoMapper.getByUserId(giveDto.getUserId());
        if (wechatUserInfo == null) {
            return Result.makeResult(ResultInfo.ERR_USERS_001);
        }
        wechatUserInfo.setOpenid("o2e4R5fsvoVbJP_I43aSFV7yTyoE");
        //TODO 暂时关闭 新用户判断
//        if (!isNewUser(targetUser.getId())){
//            return Result.makeResult(ResultInfo.ERR_USERS_002);
//        }
        //课时包查询
        ClassHourPackage classHourPackage = classHourPackageMapper.select(giveDto.getClassHourPackageId(), 0);
        if (classHourPackage == null) {
            return Result.makeResult(ResultInfo.ERR_CLASS_HOUR_PACKAGE_002);
        }
        //课时包赠送状态判断
        if (classHourPackage.getGiveType() != 0) {
            return Result.makeResult(ResultInfo.ERR_CLASS_HOUR_PACKAGE_007);
        }
        //增加 用户的课时包表 的相关数据
        UserClassHourPackage userClassHourPackage = addUserClassHourPackage(classHourPackage, targetUser.getId(), giveDto.getUserId(), now);
        //返回支付信息
        Object resultData = wxRequest.undifiedOrder("课时包赠送", getBusinessNum(userClassHourPackage.getId()), classHourPackage.getPackagePrice(),
                wechatUserInfo.getOpenid(), now, giveDto.getUserId());
        return Result.makeResult(ResultInfo.SUCCESS, resultData);
//        if (!WXConstantValue.WXPayResult.SUCCESS.getValue().equals(undifiedOrderResp.get(WXConstantValue.WXPAY_COMMON_PARAM_RETURN_CODE))){
//            throw new BaseException(ResultInfo.FAIL, undifiedOrderResp.get(WXConstantValue.WXPAY_COMMON_PARAM_RETURN_MSG)); //签名失败或者参数格式校验错误
//        }
//        if (!WXConstantValue.WXPayResult.SUCCESS.getValue().equals(undifiedOrderResp.get(WXConstantValue.WXPAY_COMMON_PARAM_RESULT_CODE))){
//            return Result.makeResult(ResultInfo.ERR_PAY_001);
//        }
//        //拼凑 调起微信的参数
//        String resultData = wxRequest.wxPaymentCallApp(undifiedOrderResp.get(WXConstantValue.RESP_PARAM_UNIFIED_ORDER_APPID),
//                undifiedOrderResp.get(WXConstantValue.RESP_PARAM_UNIFIED_ORDER_MCH_ID),
//                undifiedOrderResp.get(WXConstantValue.RESP_PARAM_UNIFIED_ORDER_PREPAY_ID),
//                undifiedOrderResp.get(WXConstantValue.WXPAY_COMMON_PARAM_NONCE_STR));
//        if (resultData == null){
//            return Result.makeResult(ResultInfo.ERR_PAY_001);
//        }
        //记录支付数据
//        paymentOrder.setWxPayCallInfo(resultData);
//        if (paymentOrder.getId() == null){
//            paymentOrderMapper.insert(paymentOrder);
//        }else{
//            paymentOrder.setGmtModifyTime(date);
//            paymentOrderMapper.update(paymentOrder);
//        }

    }

    /***
     * 创建用户课时包
     * @param giveUserId 赠送人id 可以为空
     */
    private UserClassHourPackage addUserClassHourPackage(ClassHourPackage classHourPackage, Long giveUserId, long userId, LocalDateTime time) {
        UserClassHourPackage userClassHourPackage = new UserClassHourPackage();
        userClassHourPackage.setClassHourPackageId(classHourPackage.getId());
        userClassHourPackage.setGiveUserId(giveUserId);
        userClassHourPackage.setAvailableClassHourCount(classHourPackage.getClassHourCount());
        userClassHourPackage.setPayStatus(0);
        userClassHourPackage.setCreateUserId(userId);
        userClassHourPackage.setGmtCreateTime(time);
        userClassHourPackage.setExpireTime(time.plusDays(classHourPackage.getOpenCardTimeLimit()));
        userClassHourPackageMapper.insert(userClassHourPackage);
        return userClassHourPackage;
    }

    //制定业务编码 yyyyMMddHHmmss + id
    public String getBusinessNum(long orderId) {
        return orderId + "-" + System.currentTimeMillis();
    }

    /***
     *  public Map<String, String> undifiedOrder(String description, String businessNum, String paymentBalance,
     *                                              Long payTimeSpanSec, TimeUnit timeUnit, String deviceInfo,
     *                                              String spbillCreateIp, Date date, int userId)
     */

    /**
     * 课时包-开卡
     *
     * @author evan
     */
    @Override
    public ResultModel<Boolean> open(BaseIdRequestDto baseIdRequestDto) {
        //查询用户课时包
        UserClassHourPackage userClassHourPackage = userClassHourPackageMapper.select(baseIdRequestDto.getId(), baseIdRequestDto.getUserId());
        if (userClassHourPackage == null) {
            return Result.makeResult(ResultInfo.ERR_CLASS_HOUR_PACKAGE_002);
        }
        if (userClassHourPackage.getOpenStatus() == 1) {
            return Result.makeResult(ResultInfo.ERR_CLASS_HOUR_PACKAGE_008);
        }
        //查询课时包
        ClassHourPackage classHourPackage = classHourPackageMapper.select(userClassHourPackage.getClassHourPackageId(), null);
        if (classHourPackage == null) {
            return Result.makeResult(ResultInfo.ERR_CLASS_HOUR_PACKAGE_002);
        }
        LocalDateTime now = LocalDateTime.now();
        //判断开卡有效期
        if (!now.isBefore(userClassHourPackage.getPayTime().plusDays(classHourPackage.getOpenCardTimeLimit()))) {
            return Result.makeResult(ResultInfo.ERR_CLASS_HOUR_PACKAGE_006);
        }
        Integer i = userClassHourPackageMapper.openCard(userClassHourPackage.getId(), now, now.plusDays(classHourPackage.getUseCardTimeLimit()));
        if (i > 0) {
            return Result.makeResult(ResultInfo.SUCCESS);
        } else {
            return Result.makeResult(ResultInfo.ERR_CLASS_HOUR_PACKAGE_003);
        }
    }

    /**
     * 课时包-转移申请
     *
     * @author evan
     */
    @Override
    public ResultModel<Boolean> transferApply(UserClassHourPackageTransferDto transferDto) {
        //查询用户课时包
        UserClassHourPackage userClassHourPackage = userClassHourPackageMapper.select(transferDto.getUserClassHourPackageId(), transferDto.getUserId());
        if (userClassHourPackage == null) {
            return Result.makeResult(ResultInfo.ERR_CLASS_HOUR_PACKAGE_002);
        }
        if (userClassHourPackage.getTransferUserId() != null) {
            return Result.makeResult(ResultInfo.ERR_CLASS_HOUR_PACKAGE_005);
        }
        //TODO 课时包是否允许转移
        //判断转移用户是否注册
        Users targetUser = usersMapper.getByPhoneNum(transferDto.getTargetUserPhoneNum());
        if (targetUser == null) {
            return Result.makeResult(ResultInfo.ERR_USERS_001);
        }
        //TODO 停课操作
//        studentClassRepository.suspendClass();
        int i = userClassHourPackageMapper.transferApply(transferDto.getUserClassHourPackageId(), transferDto.getUserId(), targetUser.getId());
        if (i > 0) {
            return Result.makeResult(ResultInfo.SUCCESS);
        } else {
            return Result.makeResult(ResultInfo.ERR_CLASS_HOUR_PACKAGE_004);
        }
    }

    /**
     * 课时包-取消转移申请
     *
     * @author evan
     */
    @Override
    public ResultModel<Boolean> transferApplyCancel(BaseIdRequestDto baseIdRequestDto) {
        int i = userClassHourPackageMapper.transferApplyCancel(baseIdRequestDto.getId(), baseIdRequestDto.getUserId());
        if (i > 0) {
            return Result.makeResult(ResultInfo.SUCCESS);
        } else {
            return Result.makeResult(ResultInfo.ERR_CLASS_HOUR_PACKAGE_004);
        }
    }

    /**
     * 课时包-退费申请
     *
     * @author evan
     */
    @Override
    public ResultModel<Boolean> refundApply(BaseIdRequestDto baseIdRequestDto) {
        //查询用户课时包
        UserClassHourPackage userClassHourPackage = userClassHourPackageMapper.select(baseIdRequestDto.getId(), baseIdRequestDto.getUserId());
        if (userClassHourPackage == null) {
            return Result.makeResult(ResultInfo.ERR_CLASS_HOUR_PACKAGE_002);
        }
        int i = userClassHourPackageMapper.refundApply(baseIdRequestDto.getId(), baseIdRequestDto.getUserId());
        if (i > 0) {
            return Result.makeResult(ResultInfo.SUCCESS);
        } else {
            return Result.makeResult(ResultInfo.ERR_CLASS_HOUR_PACKAGE_002);
        }
    }

    @Override
    public ResultModel<List<ClassHourPackage>> systemList(Integer pageNum, Integer pageSize) {
        Map<String, Object> map = new HashMap<>();
        map.put("recStatus", 0);
        Page p = PageHelper.startPage(pageNum, pageSize);
        List<ClassHourPackage> rewardDtoList = classHourPackageMapper.getByMapList(map);
        PageInfo<ClassHourPackage> pageInfo = new PageInfo<>(pageNum, pageSize, p.getTotal(), p.getPages(), rewardDtoList);
        return Result.makeResult(ResultInfo.SUCCESS, pageInfo);
    }

    @Override
    public ResultModel<Object> buy(UserClassHourPackageBuyDto buyInfo) {

        LocalDateTime now = LocalDateTime.now();
        ClassHourPackage classHourPackage = classHourPackageMapper.select(buyInfo.getClassHourPackageId(), 0);
        if (classHourPackage == null) {
            return Result.makeResult(ResultInfo.ERR_CLASS_HOUR_PACKAGE_002);
        }
        WechatUserInfo wechatUserInfo = wechatUserInfoMapper.getByUserId(buyInfo.getUserId());
        if (wechatUserInfo == null) {
            return Result.makeResult(ResultInfo.ERR_USERS_001);
        }
        // 创建订单
        UserClassHourPackage userClassHourPackage = addUserClassHourPackage(classHourPackage, buyInfo.getUserId(), buyInfo.getUserId(), now);
        Integer payAmount = classHourPackage.getPackagePrice();
        if (buyInfo.getCashCouponId() != null) {
            // 优惠券处理逻辑 检查用户是否拥有优惠券 支付完成时进行抵扣
//            UserCashCoupon cashCoupon = userCashCouponMapper.getAvailableByUserId(buyInfo.getCashCouponId(), buyInfo.getUserId());
//            if (cashCoupon == null){
//                return Result.makeResult(ResultInfo.ERR_CASH_COUPON_001);
//            }
            // 使用优惠券
//            int i = userCashCouponMapper.useCashCoupon(buyInfo.getCashCouponId(), buyInfo.getUserId());
//            if (i < 0){
//                return Result.makeResult(ResultInfo.ERR_CASH_COUPON_002);
//            }
            UserCashCoupon userCashCoupon = userCashCouponMapper.select(buyInfo.getCashCouponId());
            if (userCashCoupon == null) {
                return Result.makeResult(ResultInfo.ERR_CASH_COUPON_001);
            }
            if (userCashCoupon.getIsUsedStatus() == 1) {
                return Result.makeResult(ResultInfo.ERR_CASH_COUPON_003);
            }
            CashCoupon cashCoupon = cashCouponMapper.select(userCashCoupon.getCashCouponId());
            if (cashCoupon == null) {
                return Result.makeResult(ResultInfo.ERR_CASH_COUPON_002);
            }
            payAmount = payAmount - cashCoupon.getPreferentialAmount();
            userClassHourPackage.setCashCouponId(userCashCoupon.getId());
//            userClassHourPackage.setPaymentAmount(payAmount);
        }
        userClassHourPackage.setPaymentAmount(payAmount > 0 ? payAmount : 1);
        userClassHourPackageMapper.updatePayAmount(userClassHourPackage.getId(), payAmount);
        Object resultData = null;
        try {
            resultData = wxRequest.undifiedOrder(classHourPackage.getName(), getBusinessNum(userClassHourPackage.getId()), payAmount,
                    wechatUserInfo.getOpenid(), now, buyInfo.getUserId());
        } catch (WxPayException e) {
            e.printStackTrace();
        }
        Map<String, Object> resultParams = new HashMap<>();
        resultParams.put("packageId", userClassHourPackage.getId());
        resultParams.put("payParams", resultData);
        return Result.makeResult(ResultInfo.SUCCESS, resultParams);
    }


    /**
     * 查询用户所有的课时包
     *
     * @author evan
     */
    @Override
    public ResultModel<List<UserClassHourPackage>> list(Long userId, String status) {
        List<UserClassHourPackage> list = userClassHourPackageMapper.list(userId, status);

        return Result.makeResult(ResultInfo.SUCCESS, list);
    }

    @Override
    public ResultModel<ClassHourPackage> getSysPackageDetail(Long id) {
        return Result.makeResult(ResultInfo.SUCCESS, classHourPackageMapper.select(id, 0));
    }

    @Override
    public ResultModel<UserClassHourPackage> getUserClassHourPackageDetail(Long packageId, Long userId) {
        UserClassHourPackage userClassHourPackage = userClassHourPackageMapper.select(packageId, userId);
        if (!userId.equals(userClassHourPackage.getGiveUserId())) {
            return Result.makeResult(ResultInfo.ERR_PARAM_NULL, "课包与用户不一致");
        }
        return Result.makeResult(ResultInfo.SUCCESS, userClassHourPackage);
    }


    //判断用户是否从未拥有过课时包
    public boolean isNewUser(long userId) {
        List<UserClassHourPackage> list = userClassHourPackageMapper.list(userId, null);
        if (Collections.isEmpty(list)) {
            return true;
        } else {
            return false;
        }
    }
}
